package com.ayf.payment.game.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.PartitionRemoteService;
import com.ayf.payment.game.api.SiteStatisticsRemoteService;
import com.ayf.payment.game.api.cache.redis.RedisCacheUtil;
import com.ayf.payment.game.api.config.RequestConfig;
import com.ayf.payment.game.api.config.SystemInitialization;
import com.ayf.payment.game.api.controller.player.PlayerApi;
import com.ayf.payment.game.api.dto.*;
import com.ayf.payment.game.api.dto.criteria.*;
import com.ayf.payment.game.api.dto.getaway.GameRechargeGetWayDTO;
import com.ayf.payment.game.api.dto.platform.MerchantPaymentProductDTO;
import com.ayf.payment.game.api.dto.platform.MerchantSettleDTO;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.entity.*;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.httpclient.HttpClientUtils;
import com.ayf.payment.game.api.mapper.*;
import com.ayf.payment.game.api.service.*;
import com.ayf.payment.game.api.service.payment.PaymentHandleFactory;
import com.ayf.payment.game.api.service.platform.PaymentChannelService;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.type.StatisticType;
import com.ayf.payment.game.api.utils.*;
import com.ayf.payment.game.api.wx.WxSendMsgUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.swwx.charm.commons.lang.utils.BeanConvertUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private PartitionMapper partitionMapper;

    @Resource
    private MerchantMapper merchantMapper;

    @Resource
    private TemplateService templateService;

    @Resource
    private MerchantRepository merchantRepository;

    @Resource
    private ReplacementRepository replacementRepository;

    @Autowired
    private RedisCacheUtil redisCacheUtil;

    @Autowired
    private PaymentHandleFactory paymentHandleFactory;

    @Autowired
    private MerchantAccountService merchantAccountService;

    @Reference(group = "xygpay-rpc-statistics",version = "${XY_STATISTICS_DUBBO_VERSION}")
    private SiteStatisticsRemoteService siteStatisticsRemoteService;

    @Autowired
    private SystemInitialization systemInitialization;

    @Resource
    private MerchantBudgetMapper merchantBudgetMapper;

    @Resource
    private LoginHistoryMapper loginHistoryMapper;

    @Resource
    private MerchantPayOrderMapper merchantPayOrderMapper;

    @Resource
    private ReissueRecordMapper reissueRecordMapper;

    @Reference(group = "xygpay-rpc", version = "1.0.0")
    private PartitionRemoteService partitionRemoteService;

    @Resource
    private MerchantSonAndOrderMapper merchantSonAndOrderMapper;
    @Resource
    private MerchantSonMapper merchantSonMapper;
    @Autowired
    private WxSendMsgUtils wxSendMsgUtils;

    @Resource
    private MerchantConfigMapper merchantConfigMapper;

    @Resource
    private MerchantService merchantService;
    @Resource
    private PaymentChannelService paymentChannelService;
    @Resource
    private PlayerApi playerApi;

    @Autowired
    private IdGeneratorService idGeneratorService;

    @Resource
    private GroupsMapper groupsMapper;
    @Resource
    private GroupAndPartitionMapper groupAndPartitionMapper;

    @Autowired
    private OrderSplitService orderSplitService;

    @Override
    public Map<String, Object> insertOrder(OrderCriteria orderCriteria) throws Exception {
        Order order = BeanConvertUtils.convert(orderCriteria, Order.class);
        Partition partition = partitionMapper.selectByPrimaryKey(orderCriteria.getPartitionId());
        if (partition == null) {
            throw new ParameterException("分区不存在");
        }
        MerchantPaymentProductDTO merchantPaymentProductDTO=systemInitialization.productMap().get(orderCriteria.getPayProductId());
        if (merchantPaymentProductDTO == null) {
            throw new ParameterException("该通道不支持充值，请更换其它通道充值！");
        }
        if (merchantPaymentProductDTO.getPayMax()>0){
            BigDecimal rechargeMaxAmt = new BigDecimal(merchantPaymentProductDTO.getPayMax());
            if (rechargeMaxAmt.compareTo(orderCriteria.getAmount()) < 0) {
                throw new ParameterException("充值金额不能大于[" + rechargeMaxAmt + "]元");
            }
        }
        order.setGroupId(orderCriteria.getGroupId());
        if (StringUtils.isNotEmpty(orderCriteria.getGroupId()) && !"false".equals(orderCriteria.getGroupId()) && !"undefined".equals(orderCriteria.getGroupId())){
            Groups groups = groupsMapper.selectByPrimaryKey(orderCriteria.getGroupId());
            if (groups != null){
                order.setGroupName(groups.getGroupName());
            }
        } else {
            GroupAndPartition groupAndPartition = new GroupAndPartition();
            groupAndPartition.setPartitionId(orderCriteria.getPartitionId());
            List<GroupAndPartition> groupAndPartitionList =groupAndPartitionMapper.select(groupAndPartition);
            if (!CollectionUtils.isEmpty(groupAndPartitionList)){
                groupAndPartition = groupAndPartitionList.get(0);
                order.setGroupName(groupAndPartition.getGroupName());
                order.setGroupId(groupAndPartition.getGroupsId());
            }
        }
        order.setPayTypeId(orderCriteria.getPayProductId());
        order.setPayCode(merchantPaymentProductDTO.getCode());
        order.setMerchantId(partition.getMerchantId());
        order.setPartitionName(partition.getPartitionName());
        Date currentDate = DateUtils.getNowDate();
        Integer now = DateUtils.dateToInteger(currentDate);
        order.setOrderGenerateTimeIndex(now);
        String orderCreateStr =DateUtils.dateToString(currentDate, DateUtils.formatPattern_full_02);
        String orderNo = "M".concat(orderCreateStr).concat(idGeneratorService.getIdGenerator());
        order.setMerchantOrderNo(orderNo);
        order.setPlaceOrderTime(DateUtils.getMillisAfterMillis(currentDate, 1000 * 60 * 60 * 36)); //过期时间36小时
        order.setScriptStatus(0);
        order.setGameInfoId(partition.getGameInfoId());
        order.setGameInfoName(partition.getGameInfoName());
        order.setCreateTime(currentDate);
        order.setSplitFlag(0);
        String traceId = SnowFlakeUtils.getUniqueId();

        if (StringUtils.isNotBlank(orderCriteria.getGroupId())) {
            MerchantSon temp = new MerchantSon();
            temp.setGroupId(orderCriteria.getGroupId());
            MerchantSon merchantSon = merchantSonMapper.selectOne(temp);
            if (merchantSon != null) {
                MerchantSonAndOrder merchantSonAndOrder = new MerchantSonAndOrder();
                merchantSonAndOrder.setSonId(merchantSon.getId());
                merchantSonAndOrder.setLoginAccount(merchantSon.getLoginAccount());
                merchantSonAndOrder.setMerchantOrderNo(orderNo);
                merchantSonAndOrderMapper.insertSelective(merchantSonAndOrder);
            }
        }
        //创建账户
        if (orderCriteria.getIsCreateAccount() == 1) {
            playerApi.register(orderCriteria.getPhone(), partition.getMerchantId(), partition.getId());
        }
        return paymentHandleFactory.getPayment(systemInitialization.channelMap().get(merchantPaymentProductDTO.getcId()).getCode()).paymentUtil(order, partition, orderCreateStr, traceId, orderCriteria.getRedirectUrl());
    }

    @Override
    public Order selectByMerchantOrderNo(String merchantOrderNo) {

        return orderMapper.selectByMerchantOrderNo(merchantOrderNo);
    }

    @Override
    public void update(Order order) {
        orderMapper.updateByPrimaryKeySelective(order);
    }

    public GameRechargeGetWayDTO getOrderDetails(OrderCriteria orderCriteria) {
        Map map = new HashMap();
        map.put("partitionId", orderCriteria.getPartitionId());
        PartitionChangeDTO partition = this.partitionMapper.selectPartitionChangeDTO(map);
        TemplateCriteria template = this.templateService.selectTemById(partition.getTemplateId());
        OrderDTO orderDTO = (OrderDTO) BeanConvertUtils.convert(orderCriteria, OrderDTO.class);
        GameRechargeGetWayDTO gameRechargeGetWayDTO = partitionRemoteService.orderToGetWay(orderDTO, partition, template);
        if (gameRechargeGetWayDTO != null){
            gameRechargeGetWayDTO.setIsShowAdditional(template.getIsShowAdditional());
            gameRechargeGetWayDTO.setIsShowEquipment(template.getIsShowEquipment());
            gameRechargeGetWayDTO.setIsShowIntegral(template.getIsShowIntegral());
        }
        return gameRechargeGetWayDTO;
    }

    @Override
    public CommonResult orderToGetWay(Order order) {
        String traceId = SnowFlakeUtils.getUniqueId();
        String partitionId = order.getPartitionId();
        CommonResult<T> result = new CommonResult();
        result.setCode(200);
        try {

            Map map = new HashMap();
            map.put("merchantId", order.getMerchantId());
            map.put("partitionId", order.getPartitionId());
            PartitionChangeDTO partition = partitionMapper.selectPartitionChangeDTO(map);
            Merchant merchant = new Merchant();
            merchant.setId(order.getMerchantId());
            merchant = merchantMapper.selectOne(merchant);
            TemplateCriteria template = templateService.selectTemById(partition.getTemplateId());
            OrderDTO orderDTO = (OrderDTO) BeanConvertUtils.convert(order, OrderDTO.class);
            GameRechargeGetWayDTO gameRechargeGetWayDTO = partitionRemoteService.orderToGetWay(orderDTO, partition, template);
            String url = partition.getServiceAgreement() + "://" + gameRechargeGetWayDTO.getServerIp() + ":" + gameRechargeGetWayDTO.getPortNum();
            result = HttpClientUtils.doPostGetWay(url + RequestConfig.GETWAY_RECHARGE_URL,
                    gameRechargeGetWayDTO, merchant.getPrivateKey(), traceId);

            switch (result.getCode()) {
                case 200:
                    order.setScriptStatus(1);
                    LogPortal.info("{} 玩家支付成功发送支付网关成功，支付网关业务处理成功 玩家账号[{}] 商户订单号[{}] 商户ID[{}] 分区ID[{}] 分区名称[{}]", traceId, order.getRechargeNumber(), order.getMerchantOrderNo(), order.getMerchantId(), partitionId, order.getPartitionName());
                    break; //可选
                case -1:
                    LogPortal.error("{} SEND_GATEWAY_RECHARGE_FAIL 玩家支付成功发送支付网关成功，支付网关业务处理失败 玩家账号[{}] 商户订单号[{}] 商户ID[{}] 分区ID[{}] 分区名称[{}] 失败描述：[{}]", traceId, order.getRechargeNumber(), order.getMerchantOrderNo(), order.getMerchantId(), partitionId, order.getPartitionName(), result.getMsg());
                    order.setScriptStatus(-1);
                    wxSendMsgUtils.rechargeFail("玩家支付成功发送支付网关成功，支付网关业务处理失败", result.getMsg() + "，请及时处理", traceId, order);
                    break;
                case 203:
                    LogPortal.error("{} SEND_GATEWAY_RECHARGE_FAIL 玩家支付成功发送支付网关失败，支付网关业务处理失败 玩家账号[{}] 商户订单号[{}] 商户ID[{}] 分区ID[{}] 分区名称[{}] 失败描述：[{}]", traceId, order.getRechargeNumber(), order.getMerchantOrderNo(), order.getMerchantId(), partitionId, order.getPartitionName(), result.getMsg());
                    order.setScriptStatus(-1);
                    wxSendMsgUtils.rechargeFail("玩家支付成功发送支付网关失败，支付网关业务处理失败", result.getMsg() + "，请及时处理", traceId, order);
                    break;
                case 800:
                    LogPortal.error("{} SEND_GATEWAY_CONNECT_TIMEOUT_FAIL 玩家支付成功发送支付网关失败，支付网关连接失败 玩家账号[{}] 商户订单号[{}] 商户ID[{}] 分区ID[{}] 分区名称[{}] 失败描述：[{}]", traceId, order.getRechargeNumber(), order.getMerchantOrderNo(), order.getMerchantId(), partitionId, order.getPartitionName(), result.getMsg());
                    order.setScriptStatus(-1);
                    wxSendMsgUtils.rechargeFail("玩家支付成功发送支付网关失败，支付网关连接失败", result.getMsg() + "，请及时处理", traceId, order);
                    break;
                case 801:
                    LogPortal.error("{} SEND_GATEWAY_SOCKET_TIMEOUT_FAIL 玩家支付成功发送支付网关成功，支付网关响应超时 玩家账号[{}] 商户订单号[{}] 商户ID[{}] 分区ID[{}] 分区名称[{}] 失败描述：[{}]", traceId, order.getRechargeNumber(), order.getMerchantOrderNo(), order.getMerchantId(), partitionId, order.getPartitionName(), result.getMsg());
                    order.setScriptStatus(-1);
                    wxSendMsgUtils.rechargeFail("玩家支付成功发送支付网关成功，支付网关响应超时", result.getMsg() + "，请及时处理", traceId, order);
                    break;
                case 802:
                    LogPortal.error("{} SEND_GATEWAY_EXCEPTION_FAIL 玩家支付成功发送支付网关失败，支付网关发生了其他异常 玩家账号[{}] 商户订单号[{}] 商户ID[{}] 分区ID[{}] 分区名称[{}] 失败描述：[{}]", traceId, order.getRechargeNumber(), order.getMerchantOrderNo(), order.getMerchantId(), partitionId, order.getPartitionName(), result.getMsg());
                    order.setScriptStatus(-1);
                    wxSendMsgUtils.rechargeFail("玩家支付成功发送支付网关失败，支付网关发生了其他异常", result.getMsg() + "，请及时处理", traceId, order);
                    break;
                default:
            }
        } catch (Exception e) {
            LogPortal.error("{} CREATE_GATEWAY_EXCEPTION_FAIL 创建玩家支付成功发送支付网关失败，发生了{}异常 玩家账号[{}] 商户订单号[{}] 商户ID[{}] 分区ID[{}] 分区名称[{}] 失败描述：[{}]", traceId, e.getClass().getName(), order.getRechargeNumber(), order.getMerchantOrderNo(), order.getMerchantId(), partitionId, order.getPartitionName(), e.getMessage());
            LogPortal.error("{} 创建玩家支付成功发送支付网关失败，发生了{}异常 玩家账号[{}] 商户订单号[{}] 商户ID[{}] 分区ID[{}] 分区名称[{}] 失败描述：[{}]", e, traceId, e.getClass().getName(), order.getRechargeNumber(), order.getMerchantOrderNo(), order.getMerchantId(), partitionId, order.getPartitionName(), e.getMessage());
            order.setScriptStatus(-1);
            wxSendMsgUtils.rechargeFail("创建玩家支付成功发送支付网关失败，发生了" + e.getClass().getSimpleName() + "异常", e.getMessage() + "，请及时处理", traceId, order);
        } finally {
            Example example = new Example(Order.class);
            example.createCriteria().andEqualTo("merchantOrderNo", order.getMerchantOrderNo());
            Order orderdb = new Order();
            orderdb.setIsSettle(order.getIsSettle());
            orderdb.setScriptStatus(order.getScriptStatus());
            orderMapper.updateByExampleSelective(orderdb, example);
        }
        return result;
    }

    @Override
    public List<OrderAndMerchantDTO> selectProcessingOrder(OrderStatus orderStatus, long time) {
        return orderMapper.selectOrderAndMerchantInfo(orderStatus, time);
    }

    @Override
    public int selectCount(Order order) {
        return orderMapper.selectCount(order);
    }

    @Override
    public int selectCountAlterTime(Order order, long time) {
        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("orderStatus", order.getOrderStatus()).andLessThan("placeOrderTime", time);
        return orderMapper.selectCountByExample(example);
    }

    @Override
    public boolean changeOrderStatus(Order order) {
        if (order == null || StringUtils.isBlank(order.getMerchantOrderNo())) {
            throw new ParameterException("商户订单号不能为空");
        }
        if (StringUtils.isBlank(order.getId())) {
            Order temp = new Order();
            temp.setMerchantOrderNo(order.getMerchantOrderNo());
            Order dbOrder = orderMapper.selectOne(temp);
            if (dbOrder == null) {
                return false;
            }
            order.setId(dbOrder.getId());
        }
        return orderMapper.updateByPrimaryKeySelective(order) > 0;
    }

    @Override
    @Transactional
    public void changeOrderStatusAndMerchantAccount(Order dbOrder, JSONObject data) {
        MerchantConfigDTO merchantConfigDTO = merchantRepository.get(dbOrder.getMerchantId());
        dbOrder.setOrderStatus(OrderStatus.SUCCESS);
        dbOrder.setChannelRpsCode(data.getString("return_code"));
        dbOrder.setRpsMsg(data.getString("return_code"));
        dbOrder.setChannelRpsMsg(data.getString("err_code"));
        //  temp.setId(dbOrder.getId());
        if (merchantConfigDTO.getMerchantType().equals("LOWER")) {
            dbOrder.setProxyId(systemInitialization.proxyGroupMap().get(merchantConfigDTO.getSettleIdentificationId()).getMerchantId());
        }
        settleRateCount(dbOrder, merchantConfigDTO); //计算费率
        try {
            SiteStatisticsDTO siteStatisticsDTO = new SiteStatisticsDTO();
            siteStatisticsDTO.setPlayerIp(dbOrder.getClientIp());
            siteStatisticsDTO.setMerchantId(dbOrder.getMerchantId());
            siteStatisticsDTO.setGenerateTimeIndex(dbOrder.getOrderGenerateTimeIndex());
            siteStatisticsDTO.setRechargeAmt(dbOrder.getAmount());
            siteStatisticsDTO.setIncomeAmt(dbOrder.getMerchantIncome());
            siteStatisticsDTO.setPlayerAccount(dbOrder.getRechargeNumber());
            siteStatisticsRemoteService.saveSiteStatisticsOrderNumAndChargeAmt(siteStatisticsDTO);
        } catch (Exception e) {
            LogPortal.error("商户号:{} 商户订单号:{} 充值统计发生{}异常",e,dbOrder.getMerchantId(),dbOrder.getMerchantOrderNo(),e.getClass().getName());
        }

        MerchantAccountOptions merchantAccountOptions = new MerchantAccountOptions();
        merchantAccountOptions.setOptionType("充值");
        merchantAccountOptions.setOptionCash(dbOrder.getMerchantIncome());
        dbOrder.setIsSettle(0);
        dbOrder.setFinishTime(new Date());
        merchantAccountOptions.setFreezing(BigDecimal.ZERO);
        merchantAccountOptions.setCashWithdrawal(BigDecimal.ZERO);
        merchantAccountOptions.setCashWithdrawalIng(BigDecimal.ZERO);
        merchantAccountOptions.setMerchantId(dbOrder.getMerchantId());
        if (merchantConfigDTO.getMerchantType().equals("LOWER")) {
            MerchantAccountOptions merchantAccountOptionsPoxy = new MerchantAccountOptions();
            merchantAccountOptionsPoxy.setOptionType("充值");
            merchantAccountOptionsPoxy.setOptionCash(dbOrder.getProxyIncome());
            merchantAccountOptionsPoxy.setFreezing(BigDecimal.ZERO);
            merchantAccountOptionsPoxy.setCashWithdrawal(BigDecimal.ZERO);
            merchantAccountOptionsPoxy.setCashWithdrawalIng(BigDecimal.ZERO);
            merchantAccountOptionsPoxy.setMerchantId(dbOrder.getProxyId());
            merchantAccountService.updateMerchantAccount(merchantAccountOptionsPoxy);
        }
        orderMapper.updateByPrimaryKeySelective(dbOrder);
        merchantAccountService.updateMerchantAccount(merchantAccountOptions);

        //增加玩家积分
        playerApi.rechargeAdd(dbOrder.getPhone(),dbOrder.getMerchantId(),dbOrder.getMerchantOrderNo(),
                dbOrder.getAmount(),dbOrder.getPartitionId());
    }

    @Override
    public void updateScriptStatus(Order order) {

        orderMapper.updateScriptStatus(order.getMerchantOrderNo(), order.getScriptStatus());
    }

    @Override
    public OrderDTO selectOrderByOrderNo(String orderNo) {
        if (StringUtils.isBlank(orderNo)) {
            throw new ParameterException("商户订单号不能为空");
        }
        Order temp = new Order();
        temp.setMerchantOrderNo(orderNo);
        Order order = orderMapper.selectOne(temp);
        OrderDTO orderDTO = BeanConvertUtils.convert(order, OrderDTO.class);
        PaymentChannelDTO paymentChannelDTO = paymentChannelService.getPaymentChanneByCId(order.getPayChannleId());
        orderDTO.setChannelCode(paymentChannelDTO.getCode());
        MerchantConfig merchantConfig = merchantConfigMapper.selectConfigByPartitionId(order.getPartitionId());
        if(null!=merchantConfig){
            if(StringUtils.isNotEmpty(merchantConfig.getCustomerQq())){
                orderDTO.setQq(merchantConfig.getCustomerQq());
            }else {
                Merchant merchant= merchantService.find(merchantConfig.getMerchantId());
                if (!StringUtils.isEmpty(merchant.getQq())) {
                    orderDTO.setQq(merchant.getQq());
                }
            }
        }
        return orderDTO;
    }

    @Override
    public List<OrderDTO> selectByDTO(OrderSelectCriteria criteria) {
        return orderMapper.selectByDTO(criteria);
    }

    @Override
    public PageInfo<ReissueOrderDTO> selectRechargeNumbers(ReissueOrderDTO ro) {
        if (ro == null) {
            throw new ParameterException("查询信息不能为空");
        }
        if (StringUtils.isBlank(ro.getPartitionId())) {
            throw new ParameterException("分区id不能为空");
        }
        PageHelper.startPage(ro.getPageNum(), ro.getPageSize());
        List<ReissueOrderDTO> dto = orderMapper.selectRechargeNumbers(ro);
        return new PageInfo<ReissueOrderDTO>(dto);
    }

    @Override
    public List<Order> selectOrders(Order order) {
        return orderMapper.select(order);
    }

    @Override
    public ChargeOrderResponseDTO selectOrderList(OrderInfoCriteria criteria) {
        if (StringUtils.isNotEmpty(criteria.getStartTime())) {
            criteria.setOrderGenerateTimeIndexStart(DateUtils.dateToInteger(DateUtils.stringToDate(criteria.getStartTime())));
        }
        if (StringUtils.isNotEmpty(criteria.getEndTime())) {
            criteria.setOrderGenerateTimeIndexEnd(DateUtils.dateToInteger(DateUtils.stringToDate(criteria.getEndTime())));
        }
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<OrderInfoDTO> dbList = orderMapper.selectOrderInfo(criteria);
        PageInfo pageInfo = new PageInfo(dbList);
        ChargeOrderResponseDTO dto = orderMapper.selectSumAmountAndFee(criteria);
        if (dbList.size() > 0) {
            dto.setNum(pageInfo.getTotal());
            dto.setList(pageInfo.getList());
            dto.setPageNum(pageInfo.getPageNum());
            dto.setPageSize(pageInfo.getPageSize());
        }
        Date dayBeforeDay = DateUtils.getDayTimeBeforeDay(1);
        String s1 = DateUtils.dateToString(dayBeforeDay, "yyyy-MM-dd 00:00:00");
        String s2 = DateUtils.dateToString(dayBeforeDay, DateUtils.formatPattern_full);
        Integer s3 = Integer.valueOf(DateUtils.dateToString(dayBeforeDay, DateUtils.formatPattern_Short));
        OrderInfoCriteria temp = new OrderInfoCriteria();
        temp.setStartTime(s1);
        temp.setEndTime(s2);
        temp.setOrderGenerateTimeIndexStart(s3);
        temp.setOrderGenerateTimeIndexEnd(s3);
        temp.setMerchantId(criteria.getMerchantId());
        temp.setProxyId(criteria.getProxyId());
        temp.setProxyIds(criteria.getProxyIds());
        temp.setSplitFlag(criteria.getSplitFlag());
        ChargeOrderResponseDTO amountAndFee = orderMapper.selectSumAmountAndFee(temp);
        BigDecimal zero = new BigDecimal(0);
        dto.setYesterdayTotal(amountAndFee.getSuccessTotal() == null ? 0L : amountAndFee.getSuccessTotal());
        dto.setYesterdayTotalAmount(amountAndFee.getSuccessTotalAmount() == null ? zero : amountAndFee.getSuccessTotalAmount());
        dto.setYesterdayMerchantTotalIncome(amountAndFee.getMerchantTotalIncome() == null ? zero : amountAndFee.getMerchantTotalIncome());
        dto.setYesterdayPlatformTotalIncome(amountAndFee.getPlatformTotalIncome() == null ? zero : amountAndFee.getPlatformTotalIncome());
        dto.setYesterdayProxyTotalIncome(amountAndFee.getProxyTotalIncome() == null ? zero : amountAndFee.getProxyTotalIncome());
        return dto;
    }

    @Override
    public List<OrderInfoDTO> orderList(OrderInfoCriteria criteria) {
        if (StringUtils.isNotEmpty(criteria.getStartTime())) {
            criteria.setOrderGenerateTimeIndexStart(DateUtils.dateToInteger(DateUtils.stringToDate(criteria.getStartTime())));
        }
        if (StringUtils.isNotEmpty(criteria.getEndTime())) {
            criteria.setOrderGenerateTimeIndexEnd(DateUtils.dateToInteger(DateUtils.stringToDate(criteria.getEndTime())));
        }
        return orderMapper.selectOrderInfo(criteria);
    }

    @Override
    public List<MerchantSettleDTO> merchantSettleByOrderCount(Integer orderGenerateTimeIndexEnd, Integer orderGenerateTimeIndexStrat, String settleDate, Short settleCycle) {
        return orderMapper.merchantSettleByOrderCount(orderGenerateTimeIndexEnd, orderGenerateTimeIndexStrat, settleDate, settleCycle);
    }

    @Override
    public List<MerchantSettleDTO> merchantSettleByOrderCountProxy(Integer orderGenerateTimeIndexEnd, Integer orderGenerateTimeIndexStrat, String settleDate, Short settleCycle) {
        return orderMapper.merchantSettleByOrderCountProxy(orderGenerateTimeIndexEnd, orderGenerateTimeIndexStrat, settleDate, settleCycle);
    }


    @Override
    public Map<Integer, Map<String, Object>> selectSumAmount(OrderInfoCriteria cri) {
        return orderMapper.selectSumAmount(cri);
    }

    @Override
    public ChargeOrderResponseDTO selectSumAmountAndFee(OrderInfoCriteria cri) {
        return orderMapper.selectSumAmountAndFee(cri);
    }

    @Override
    public Map<Integer, Map<String, Object>> selectSumProxyIncome(OrderInfoCriteria cri) {
        return orderMapper.selectSumProxyIncome(cri);
    }

    @Override
    public List<PartitionStatisticsDTO> selectPartitionChargeSuccessDetailList(PartitionStatisticsCriteria criteria) {
        List<PartitionStatisticsDTO> partitionStatisticsDTOList = orderMapper.selectPartitionChargeSuccessDetailList(criteria);
        if (!CollectionUtils.isEmpty(partitionStatisticsDTOList)) {
            BigDecimal allTotalAmt = orderMapper.selectPartitionChargeSuccessTotalAmt(criteria);
            for (PartitionStatisticsDTO partitionStatisticsDTO : partitionStatisticsDTOList) {
                if (partitionStatisticsDTO.getTotalAmount() == null) {
                    partitionStatisticsDTO.setAmtRatio("0.00%");
                } else {
                    BigDecimal tmpAmt = partitionStatisticsDTO.getTotalAmount().divide(allTotalAmt, 4, BigDecimal.ROUND_HALF_EVEN);
                    String ratioAmt = (tmpAmt.multiply(BigDecimal.valueOf(100))).setScale(2, BigDecimal.ROUND_DOWN).toString();
                    partitionStatisticsDTO.setAmtRatio(ratioAmt.concat("%"));
                }
            }
        }
        return partitionStatisticsDTOList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void paymentOrder(Order order, JSONObject dataObject) {
        MerchantConfigDTO merchantConfigDTO = merchantRepository.get(order.getMerchantId());
        order.setChannelRpsCode(dataObject.getString("err_code"));
        order.setRpsMsg(dataObject.getString("err_code_desc"));
        order.setChannelRpsMsg(dataObject.getString("err_code_desc"));

        order.setFinishTime(new Date());
        if (order.getOrderStatus().equals(OrderStatus.SUCCESS)) {
            if (merchantConfigDTO.getMerchantType().equals("LOWER")) {
                order.setProxyId(systemInitialization.proxyGroupMap().get(merchantConfigDTO.getSettleIdentificationId()).getMerchantId());
            }
            settleRateCount(order, merchantConfigDTO); //计算费率
            try {
                SiteStatisticsDTO siteStatisticsDTO = new SiteStatisticsDTO();
                siteStatisticsDTO.setPlayerIp(order.getClientIp());
                siteStatisticsDTO.setMerchantId(order.getMerchantId());
                siteStatisticsDTO.setGenerateTimeIndex(order.getOrderGenerateTimeIndex());
                siteStatisticsDTO.setRechargeAmt(order.getAmount());
                siteStatisticsDTO.setIncomeAmt(order.getMerchantIncome());
                siteStatisticsDTO.setPlayerAccount(order.getRechargeNumber());
                siteStatisticsRemoteService.saveSiteStatisticsOrderNumAndChargeAmt(siteStatisticsDTO);
            } catch (Exception e) {
                LogPortal.error("商户号:{} 商户订单号:{} 充值统计发生{}异常",e,order.getMerchantId(),order.getMerchantOrderNo(),e.getClass().getName());
            }
            MerchantAccountOptions merchantAccountOptions = new MerchantAccountOptions();
            merchantAccountOptions.setOptionType("充值");
            merchantAccountOptions.setOptionCash(order.getMerchantIncome());
            order.setIsSettle(0);
            merchantAccountOptions.setFreezing(BigDecimal.ZERO);
            merchantAccountOptions.setCashWithdrawal(BigDecimal.ZERO);
            merchantAccountOptions.setCashWithdrawalIng(BigDecimal.ZERO);
            merchantAccountOptions.setMerchantId(order.getMerchantId());
            if (1 == order.getSplitFlag()){
                merchantAccountOptions.setSplitAmt(merchantAccountOptions.getOptionCash());
            }
            if (merchantConfigDTO.getMerchantType().equals("LOWER")) {
                MerchantAccountOptions merchantAccountOptionsPoxy = new MerchantAccountOptions();
                merchantAccountOptionsPoxy.setOptionType("代理商收费");
                merchantAccountOptionsPoxy.setOptionCash(order.getProxyIncome());
                merchantAccountOptionsPoxy.setFreezing(BigDecimal.ZERO);
                merchantAccountOptionsPoxy.setCashWithdrawalIng(BigDecimal.ZERO);
                merchantAccountOptionsPoxy.setMerchantId(order.getProxyId());
                merchantAccountService.updateMerchantAccount(merchantAccountOptionsPoxy);
            }
            merchantAccountService.updateMerchantAccount(merchantAccountOptions);
            //增加玩家积分
            playerApi.rechargeAdd(order.getPhone(), order.getMerchantId(), order.getMerchantOrderNo(), order.getAmount(), order.getPartitionId());
        }
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void changeOrderIsSettleByDate(Integer merchantId, String orderDate) {

        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("merchantId", merchantId).andEqualTo("orderGenerateTimeIndex", orderDate);
        Order order = new Order();
        order.setIsSettle(1);
        orderMapper.updateByExampleSelective(order, example);
    }

    @Override
    public StatisticsPageDTO topUpStatistics(StatisticsCriteria statistics) {
        if (StringUtils.isBlank(statistics.getType())) {
            throw new ParameterException("统计类型不能为空");
        }
        StatisticsPageDTO statisticsPageSum = null;
        StatisticsPageDTO yesterDayStatisticsPageSum = null;
        List<StatisticsDTO> dtoList = new ArrayList<>();
        if (statistics.getType().equals(StatisticType.PARTITION.name())) {
            PageHelper.startPage(statistics.getPageNum(), statistics.getPageSize());
            dtoList = orderMapper.partitionStatistic(statistics);
            calculatePercentage(dtoList);
        } else if (statistics.getType().equals(StatisticType.TEMPLATE.name())) {
            PageHelper.startPage(statistics.getPageNum(), statistics.getPageSize());
            dtoList = orderMapper.templateStatistic(statistics);
            calculatePercentage(dtoList);
        } else if (statistics.getType().equals(StatisticType.PAY.name())) {
            StatisticsNoPageCriteria statisticsNoPageCriteria =BeanConvertUtils.convert(statistics,StatisticsNoPageCriteria.class);
            dtoList = orderMapper.payTypeStatistic(statisticsNoPageCriteria);
        } else if (statistics.getType().equals(StatisticType.GROUP.name())) {
            PageHelper.startPage(statistics.getPageNum(), statistics.getPageSize());
            dtoList = orderMapper.groupStatistic(statistics);
            OrderInfoCriteria criteria = new OrderInfoCriteria();
            criteria.setMerchantId(statistics.getMerchantId());
            criteria.setOrderGenerateTimeIndexEnd(statistics.getOrderGenerateTimeIndexEnd());
            criteria.setOrderGenerateTimeIndexStart(statistics.getOrderGenerateTimeIndexStart());
            ChargeOrderResponseDTO responseDTO = orderMapper.selectSumAmountAndFee(criteria);
            BigDecimal successTotalAmount = responseDTO.getSuccessTotalAmount();
            if (successTotalAmount == null || successTotalAmount.compareTo(BigDecimal.valueOf(0)) == 0) {
                successTotalAmount = BigDecimal.ONE;
            }
            for (StatisticsDTO dto : dtoList) {
                dto.setProportion(dto.getAmount().multiply(new BigDecimal(100)).divide(successTotalAmount, 2, RoundingMode.HALF_UP).toString() + "%");
            }
        } else if (statistics.getType().equals(StatisticType.NUMBER.name())) {
            PageHelper.startPage(statistics.getPageNum(), statistics.getPageSize());
            dtoList = orderMapper.numberStatistic(statistics);
        } else if (statistics.getType().equals(StatisticType.HOURS.name())) {
            if (StringUtils.isBlank(statistics.getDate())) {
                throw new ParameterException("时段统计，统计日期不能为空");
            }
            StatisticsNoPageCriteria statisticsNoPageCriteria =BeanConvertUtils.convert(statistics,StatisticsNoPageCriteria.class);
            Map<Integer, StatisticsDTO> dbMap = orderMapper.hoursStatistic(statisticsNoPageCriteria);
            for (int i = 0; i < 24; i++) {
                if (dbMap.get(i) != null) {
                    dtoList.add(dbMap.get(i));
                } else {
                    StatisticsDTO dto = new StatisticsDTO();
                    dto.setHour(i);
                    dto.setAmount(BigDecimal.ZERO);
                    dto.setNumber(0);
                    dtoList.add(dto);
                }
            }
        } else if (statistics.getType().equals(StatisticType.DAILY.name())) {
            PageHelper.startPage(statistics.getPageNum(), statistics.getPageSize());
            StatisticsNoPageCriteria statisticsNoPageCriteria =BeanConvertUtils.convert(statistics,StatisticsNoPageCriteria.class);
            dtoList = orderMapper.dailyStatistic(statistics);
            dateFormat(dtoList);
            if (Objects.nonNull(statistics.getProxyId())){ // 表示 GM后台代理 每日收益查询
                statisticsPageSum = orderMapper.dailySumStatistic(statisticsNoPageCriteria);
                StatisticsNoPageCriteria yesterdayStatisticsNoPageCriteria = BeanConvertUtils.convert(statistics,StatisticsNoPageCriteria.class);
                Integer yesterdayDateIndex = DateUtils.dateToInteger(DateUtils.getDayBeforeDay(1));
                yesterdayStatisticsNoPageCriteria.setOrderGenerateTimeIndexStart(yesterdayDateIndex);
                yesterdayStatisticsNoPageCriteria.setOrderGenerateTimeIndexEnd(yesterdayDateIndex);
                yesterDayStatisticsPageSum = orderMapper.dailySumStatistic(yesterdayStatisticsNoPageCriteria);
            }
        } else if (statistics.getType().equals(StatisticType.MERCHANT.name())) {
            PageHelper.startPage(statistics.getPageNum(), statistics.getPageSize());
            StatisticsNoPageCriteria statisticsNoPageCriteria =BeanConvertUtils.convert(statistics,StatisticsNoPageCriteria.class);
            dtoList = orderMapper.merchantStatistic(statisticsNoPageCriteria);
        } else if (statistics.getType().equals(StatisticType.MERCHANTDAILY.name())) {
            PageHelper.startPage(statistics.getPageNum(), statistics.getPageSize());
            dtoList = orderMapper.merchantDailyStatistic(statistics);
            dateFormat(dtoList);
        } else if (statistics.getType().equals(StatisticType.PROXYDAILY.name())) {
            PageHelper.startPage(statistics.getPageNum(), statistics.getPageSize());
            dtoList = orderMapper.proxyDailyStatistic(statistics);
            dateFormat(dtoList);
        }
        PageInfo<StatisticsDTO> pageInfo = new PageInfo<>(dtoList);
        StatisticsPageDTO dto = BeanConvertUtils.convert(pageInfo, StatisticsPageDTO.class);
        if (Objects.nonNull(statisticsPageSum)){
            dto.setMerchantTotalIncome(statisticsPageSum.getMerchantTotalIncome());
            dto.setPlatformTotalIncome(statisticsPageSum.getPlatformTotalIncome());
            dto.setProxyTotalIncome(statisticsPageSum.getProxyTotalIncome());
            dto.setSuccessTotal(statisticsPageSum.getSuccessTotal());
            dto.setSuccessTotalAmount(statisticsPageSum.getSuccessTotalAmount());

            dto.setYesterdayMerchantTotalIncome(yesterDayStatisticsPageSum.getMerchantTotalIncome());
            dto.setYesterdayPlatformTotalIncome(yesterDayStatisticsPageSum.getPlatformTotalIncome());
            dto.setYesterdayProxyTotalIncome(yesterDayStatisticsPageSum.getProxyTotalIncome());
            dto.setYesterdaySuccessTotal(yesterDayStatisticsPageSum.getSuccessTotal());
            dto.setYesterdaySuccessTotalAmount(yesterDayStatisticsPageSum.getSuccessTotalAmount());
        }
        return dto;
    }

    private void dateFormat(List<StatisticsDTO> dtoList) {
        for (StatisticsDTO dto : dtoList) {
            String s = DateUtils.stringFormat(dto.getDate(), DateUtils.formatPattern_Short, DateUtils.formatPattern);
            dto.setDate(s);
        }
    }

    private void calculatePercentage(List<StatisticsDTO> dtoList) {
        BigDecimal totalAmount = new BigDecimal(0);
        for (StatisticsDTO dto : dtoList) {
            totalAmount = totalAmount.add(dto.getAmount());
        }
        if (totalAmount.compareTo(BigDecimal.valueOf(0)) == 0) {
            totalAmount = BigDecimal.ONE;
        }
        for (StatisticsDTO dto : dtoList) {
            dto.setProportion(dto.getAmount().multiply(new BigDecimal(100)).divide(totalAmount, 2, RoundingMode.HALF_UP).toString() + "%");
        }
    }

    @Override
    public List<ChannelStatisticsDTO> channelStatistic(StatisticsCriteria statistics) {
        if (statistics.getOrderGenerateTimeIndexStart() != null) {
            statistics.setStartTime(DateUtils.stringFormat(statistics.getOrderGenerateTimeIndexStart() - 1 + "",
                    DateUtils.formatPattern_Short, "yyyy-MM-dd 00:00:00"));
            statistics.setOrderGenerateTimeIndexStart(statistics.getOrderGenerateTimeIndexStart() - 2);
        }
        if (statistics.getOrderGenerateTimeIndexEnd() != null) {
            statistics.setEndTime(DateUtils.stringFormat(statistics.getOrderGenerateTimeIndexEnd() - 1 + "",
                    DateUtils.formatPattern_Short, "yyyy-MM-dd 23:59:59"));
            statistics.setOrderGenerateTimeIndexEnd(statistics.getOrderGenerateTimeIndexEnd() - 1);
        }
        return orderMapper.channelStatistic(statistics);
    }

    @Override
    public boolean cleanOrderAndSettle(CleanCriteria clean) {
        if (clean.getEndDate() == null) {
            throw new ParameterException("清理结束日期不能为空");
        }
        clean.setEndDateStr(DateUtils.stringFormat(clean.getEndDate().toString(), DateUtils.formatPattern_Short,
                DateUtils.formatPattern_full));
        orderMapper.cleanOrder(clean);
//        merchantCashOutMapper.cleanSettle(clean);
        loginHistoryMapper.cleanLoginHistory(clean);
        merchantPayOrderMapper.cleanPayOrder(clean);
        merchantBudgetMapper.cleanBudgets(clean);
        siteStatisticsRemoteService.cleanSiteStatistics(clean);
        reissueRecordMapper.cleanReissueRecord(clean);
        return true;
    }

    @Override
    public void settleRateCount(Order order, MerchantConfigDTO merchantConfigDTO) {
        BigDecimal rateChannel = systemInitialization.productDTO(order.getPayTypeId()).getPaymentRate();
        if (merchantConfigDTO.getMerchantType().equals("LOWER")) {
            BigDecimal rateProxyMerchant = systemInitialization.settleRateMap().get(merchantConfigDTO.getProxyIdentificationId()).get(order.getPayTypeId());
            BigDecimal rateLower = systemInitialization.proxyGroupSettleRateMap().get(merchantConfigDTO.getSettleIdentificationId()).get(order.getPayTypeId());
            BigDecimal merchantIncome = order.getAmount().multiply(rateLower.multiply(BigDecimal.valueOf(0.01)));
            order.setMerchantIncome(BigDecimalUtil.amtHalfDown(merchantIncome));  //商户
            BigDecimal proxyIncome = order.getAmount().multiply((rateProxyMerchant.subtract(rateLower)).multiply(BigDecimal.valueOf(0.01)));
            order.setProxyIncome(proxyIncome); //代理商
            BigDecimal platformIncome = order.getAmount().multiply((rateChannel.subtract(rateProxyMerchant)).multiply(BigDecimal.valueOf(0.01)));
            order.setPlatformIncome(platformIncome); //平台收入
            BigDecimal fee = order.getAmount().subtract(merchantIncome);
            order.setFee(fee);
        } else {
            BigDecimal rateMerchant = systemInitialization.settleRateMap().get(merchantConfigDTO.getSettleIdentificationId()).get(order.getPayTypeId());
            BigDecimal merchantIncome = order.getAmount().multiply(rateMerchant.multiply(BigDecimal.valueOf(0.01)));
            order.setMerchantIncome(BigDecimalUtil.amtHalfDown(merchantIncome)); //商户
            order.setProxyIncome(BigDecimal.ZERO); //代理商
            BigDecimal platformIncome = order.getAmount().multiply((rateChannel.subtract(rateMerchant)).multiply(BigDecimal.valueOf(0.01)));
            order.setPlatformIncome(platformIncome); //平台收入
            BigDecimal fee = order.getAmount().subtract(order.getMerchantIncome());
            order.setFee(fee);
        }
        BigDecimal channelIncome = order.getAmount().multiply((new BigDecimal("100.00").subtract(rateChannel)).multiply(BigDecimal.valueOf(0.01)));
        order.setChannelIncome(channelIncome);
    }

    @Override
    public void changeOrderIsSettle(String settleDate) {
        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("orderGenerateTimeIndex", settleDate).andEqualTo("isSettle", 0);
        Order order = new Order();
        order.setIsSettle(1);
        orderMapper.updateByExampleSelective(order, example);
    }

    @Override
    public CommonResult retryOrders(String[] merchantOrderNos) {
        CommonResult commonResult = new CommonResult();
        commonResult.setCode(200);
        commonResult.setMsg("成功下发重试");
        List<Order> orderList = orderMapper.getReTryOrder(merchantOrderNos);
        StringBuffer buffer = new StringBuffer();
        List<Order> list = new ArrayList<>();
        for (Order order : orderList) {
            try {
                order.setScriptStatus(0);
                updateScriptStatus(order);
                list.add(order);
            } catch (Exception e) {
                buffer.append(order.getMerchantOrderNo()).append(",");
                LogPortal.error("RETRY_SCRIPT_ORDER 重试发送订单{{}}脚本生出现异常。", e, order.getMerchantOrderNo());
            }
        }
        new Thread(new RetryOrdersRunnable(list)).start();
        if (buffer.length() > 0) {
            commonResult.setMsg("成功下发重试,部分失败订单：" + buffer.toString());
        }
        return commonResult;
    }

    @Override
    public CommonResult checkPayOrder(String merchantOrderNo) {
        CommonResult commonResult = new CommonResult();
        commonResult.setCode(200);
        String traceId = "Manual Operation" + SnowFlakeUtils.getTraceId();
        OrderAndMerchantDTO orderAndMerchantDTO = orderMapper.getOrderAndMerchantInfo(OrderStatus.PROCESSING, merchantOrderNo);
        if (null == orderAndMerchantDTO) {
            commonResult.setMsg("订单已处理完成，不需要进行查询");
            return commonResult;
        }
        paymentHandleFactory.getPayment(systemInitialization.channelDTO(orderAndMerchantDTO.getPayChannleId()).getCode()).queryPayOrder(orderAndMerchantDTO, traceId);
        orderAndMerchantDTO = orderMapper.getOrderAndMerchantInfo(OrderStatus.PROCESSING, merchantOrderNo);
        if (orderAndMerchantDTO != null) {
            commonResult.setMsg("通道处理中");
        } else {
            commonResult.setMsg("通道已处理");
        }
        return commonResult;
    }

    @Override
    public void updateOrderStatus(String merchantOrderNo, long placeTime) {
        orderMapper.updateOrderStatus(merchantOrderNo, placeTime, new Date());
    }

    class RetryOrdersRunnable implements Runnable {
        private List<Order> list;

        public RetryOrdersRunnable(List<Order> list) {
            this.list = list;
        }

        @Override
        public void run() {
            try {
                this.list.forEach((order) -> {
                    orderToGetWay(order);
                });
            } catch (Exception e) {
                LogPortal.error("RETRY_SCRIPT_ORDER_ERROR 重试发送订单{{}}脚本生出现异常。", e);
            }


        }
    }

    @Override
    public List<OrderInfoDTO> selectSonOrderList(OrderInfoCriteria criteria) {
        return orderMapper.selectSonOrderList(criteria);
    }

    @Override
    public ChargeOrderResponseDTO selectSumSonAmount(OrderInfoCriteria cri) {
        return orderMapper.selectSumSonAmount(cri);
    }

    @Override
    public ChargeOrderResponseDTO partitionStatisticSum(StatisticsCriteria statistics) {
        return orderMapper.partitionStatisticSum(statistics);
    }

    @Override
    public CommonResult correctOrder(String merchantOrderNo,String ip) {
        CommonResult commonResult = new CommonResult();
        commonResult.setCode(200);
        commonResult.setMsg("成功");
        Order  order = orderMapper.getCorrectOrders(merchantOrderNo);
        order.setOperateIp(ip);
        if(null==order){
            commonResult.setCode(-1);
            commonResult.setMsg("订单不存在或状态错误！");
        }else {
            String traceId = SnowFlakeUtils.getUniqueId();
            try {
                order.setWxNotice(2);
                CommonResult resultGetway = orderToGetWay(order);
                commonResult.setCode(resultGetway.getCode());
            }catch (Exception e){
                LogPortal.error("{} 请求充值网关异常!", e,traceId);
                commonResult.setCode(-1);
                commonResult.setMsg("手动调单失败,请求网关异常:"+traceId);
            }
            if(commonResult.getCode()!=200){
                commonResult.setCode(-1);
                commonResult.setMsg("手动调单失败,请求网关异常！");
            }else {
                order.setIsSettle(0);
                order.setScriptStatus(1);
                order.setOrderStatus(OrderStatus.SUCCESS);
                order.setFinishTime(new Date());
                order.setCorrectStatus(1);
                MerchantConfigDTO merchantConfigDTO = merchantRepository.get(order.getMerchantId());
                BigDecimal rateChannel = systemInitialization.productDTO(order.getPayTypeId()).getPaymentRate();
                if (merchantConfigDTO.getMerchantType().equals("LOWER")) {
                    BigDecimal rateProxyMerchant = systemInitialization.settleRateMap().get(merchantConfigDTO.getProxyIdentificationId()).get(order.getPayTypeId());
                    BigDecimal rateLower = systemInitialization.proxyGroupSettleRateMap().get(merchantConfigDTO.getSettleIdentificationId()).get(order.getPayTypeId());
                    BigDecimal merchantIncome = order.getAmount().multiply(rateLower.multiply(BigDecimal.valueOf(0.01)));
                    order.setMerchantIncome(BigDecimalUtil.amtHalfDown(merchantIncome));  //商户
                    BigDecimal proxyIncome = order.getAmount().multiply((rateProxyMerchant.subtract(rateLower)).multiply(BigDecimal.valueOf(0.01)));
                    order.setProxyIncome(proxyIncome); //代理商
                    order.setProxyId(systemInitialization.proxyGroupMap().get(merchantConfigDTO.getSettleIdentificationId()).getMerchantId());
                    BigDecimal platformIncome = order.getAmount().multiply((rateChannel.subtract(rateProxyMerchant)).multiply(BigDecimal.valueOf(0.01)));
                    order.setPlatformIncome(platformIncome); //平台收入
                    BigDecimal fee = order.getAmount().subtract(merchantIncome);
                    order.setFee(fee);
                } else {
                    BigDecimal rateMerchant = systemInitialization.settleRateMap().get(merchantConfigDTO.getSettleIdentificationId()).get(order.getPayTypeId());
                    BigDecimal merchantIncome = order.getAmount().multiply(rateMerchant.multiply(BigDecimal.valueOf(0.01)));
                    order.setMerchantIncome(BigDecimalUtil.amtHalfDown(merchantIncome)); //商户
                    order.setProxyIncome(BigDecimal.ZERO); //代理商
                    BigDecimal platformIncome = order.getAmount().multiply((rateChannel.subtract(rateMerchant)).multiply(BigDecimal.valueOf(0.01)));
                    order.setPlatformIncome(platformIncome); //平台收入
                    BigDecimal fee = order.getAmount().subtract(order.getMerchantIncome());
                    order.setFee(fee);
                }
                orderMapper.updateByPrimaryKey(order);
            }

        }
        return commonResult;
    }

    @Override
    public List<OrderInfoDTO> todayLastOrderList(OrderInfoCriteria criteria) {
        if (StringUtils.isNotEmpty(criteria.getStartTime())) {
            criteria.setOrderGenerateTimeIndexStart(DateUtils.dateToInteger(DateUtils.stringToDate(criteria.getStartTime())));
        }
        if (StringUtils.isNotEmpty(criteria.getEndTime())) {
            criteria.setOrderGenerateTimeIndexEnd(DateUtils.dateToInteger(DateUtils.stringToDate(criteria.getEndTime())));
        }
        return orderMapper.todayLastOrderList(criteria);
    }

    @Override
    public CommonResult deleteOrders(String[] merchantOrderNos) {
        CommonResult commonResult = new CommonResult();
        commonResult.setCode(200);
        commonResult.setMsg("删除成功");
        try {
            orderMapper.deleteOrders(merchantOrderNos);
        }catch (Exception e){
            LogPortal.error("批量删除订单异常！订单号：[{}]", e, JsonUtils.strToJson(merchantOrderNos));
            commonResult.setCode(-1);
            commonResult.setMsg("删除失败");
        }
        return commonResult;
    }

    @Override
    public CommonResult updateOrderInfo(OrderCriteria criteria) {
        CommonResult commonResult = new CommonResult();
        commonResult.setCode(200);
        commonResult.setMsg("修改成功");

        Example example = new Example(Order.class);
        Example.Criteria updateCriteria = example.createCriteria();
        updateCriteria.andEqualTo("merchantOrderNo",criteria.getMerchantOrderNo());
        Order order = new Order();
        order.setRechargeNumber(criteria.getRechargeNumber());

        if (StringUtils.isNotEmpty(criteria.getPartitionId())){
            order.setPartitionName(criteria.getPartitionName());
            order.setPartitionId(criteria.getPartitionId());
            Partition newPartition =  partitionMapper.selectByPrimaryKey(criteria.getPartitionId());
            order.setGameInfoId(newPartition.getGameInfoId());
            order.setGameInfoName(newPartition.getGameInfoName());
        }
        orderMapper.updateByExampleSelective(order,example);
        if (criteria.getIsSendGateWay()==1){ // 发送网关
            try {
                List<Order> existsOrderList = orderMapper.selectByExample(example);
                List<Order> sendGateWayOrderList = new ArrayList<>();
                for (Order order2 : existsOrderList) {
                    try {
                        order2.setScriptStatus(0);
                        updateScriptStatus(order2);
                        sendGateWayOrderList.add(order2);
                    } catch (Exception e) {
                        LogPortal.error("RETRY_SCRIPT_ORDER 重试发送订单{{}}脚本生出现异常。", e, order.getMerchantOrderNo());
                    }
                }
                new Thread(new RetryOrdersRunnable(sendGateWayOrderList)).start();
            } catch (Exception e) {
                LogPortal.error("订单号:{} 发送网关发生{}异常",e,criteria.getMerchantOrderNo(),e.getClass().getName());
            }
        }
        return commonResult;
    }

    @Override
    public OrderInfoDTO playerQueryOrderNo(String merchantOrderNo) {
        return orderMapper.playerQueryOrderNo(merchantOrderNo,DateUtils.dateToInteger(DateUtils.getDayBeforeDay(2)));
    }

    @Transactional
    @Override
    public void saveOrder(Order order) {
        orderMapper.insertSelective(order);
        order.getSplitDTOList().forEach(item->{
            item.setOrderId(order.getId());
            orderSplitService.insertOrderSplit(item);
        });
    }
}






